﻿// <copyright file="MainViewModel.cs" company="Microsoft Corporation">
// Copyright (c) 2010 Microsoft Corporation All Rights Reserved
// </copyright>
// <author>Michael S. Scherotter</author>
// <email>mischero@microsoft.com</email>
// <date>2010-09-13</date>
// <summary>MainViewModel calss definition</summary>

namespace MostPopular
{
    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.IO.IsolatedStorage;
    using System.Linq;
    using MostPopular.ViewModels;

    /// <summary>
    /// The main view model
    /// </summary>
    public class MainViewModel : INotifyPropertyChanged, IDisposable
    {
        /// <summary>
        /// The selected item showed in the Details page
        /// </summary>
        private NYTimes.Data.MostPopularItem selectedItem;

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "These are disposed in the Dispose Function.")]
        public MainViewModel()
        {
            this.MostEmailed = new NYTimes.MostPopular
            {
                MaxResults = 20,
                ResourceType = NYTimes.MostPopularResourceType.MostEmailed,
                TimePeriod = 1
            };

            this.MostShared = new NYTimes.MostPopular
            {
                MaxResults = 20,
                ResourceType = NYTimes.MostPopularResourceType.MostShared,
                TimePeriod = 1
            };

            this.MostViewed = new NYTimes.MostPopular
            {
                MaxResults = 20,
                ResourceType = NYTimes.MostPopularResourceType.MostViewed,
                TimePeriod = 1
            };

            this.Shared = new ObservableCollection<ShareVia>();

            this.Shared.Add(new ShareVia { Name = "Digg", IsEnabled = true, Id = "digg" });
            this.Shared.Add(new ShareVia { Name = "Email", IsEnabled = true, Id = "email" });
            this.Shared.Add(new ShareVia { Name = "Facebook", IsEnabled = true, Id = "facebook" });
            this.Shared.Add(new ShareVia { Name = "Mixx", IsEnabled = true, Id = "mixx" });
            this.Shared.Add(new ShareVia { Name = "Myspace", IsEnabled = true, Id = "myspace" });
            this.Shared.Add(new ShareVia { Name = "Permalink", IsEnabled = true, Id = "permalink" });
            this.Shared.Add(new ShareVia { Name = "TimesPeople", IsEnabled = true, Id = "timespeople" });
            this.Shared.Add(new ShareVia { Name = "Twitter", IsEnabled = true, Id = "twitter" });
            this.Shared.Add(new ShareVia { Name = "Yahoo! Buzz", IsEnabled = true, Id = "yahoobuzz" });

            this.LoadSettings();
        }

        #region Events
        /// <summary>
        /// Property changed event handler
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        /// <summary>
        /// Gets or sets a value indicating whether to return all sources
        /// </summary>
        public bool IsAllSources
        {
            get
            {
                bool isAllSources = true;

                foreach (var share in this.Shared)
                {
                    IsolatedStorageSettings.ApplicationSettings[share.Id] = share.IsEnabled;

                    if (!share.IsEnabled)
                    {
                        isAllSources = false;
                    }
                }

                return isAllSources;
            }

            set
            {
                foreach (var source in this.Shared)
                {
                    source.IsEnabled = value;
                }

                this.NotifyPropertyChanged("IsAllSources");
                this.NotifyPropertyChanged("IsSourceNameEnabled");
            }
        }

        /// <summary>
        /// Gets the most emailed items
        /// </summary>
        public NYTimes.MostPopular MostEmailed { get; private set; }

        /// <summary>
        /// Gets the most viewed items
        /// </summary>
        public NYTimes.MostPopular MostViewed { get; private set; }

        /// <summary>
        /// Gets the most shared items
        /// </summary>
        public NYTimes.MostPopular MostShared { get; private set; }

        /// <summary>
        /// Gets the sharing vectors
        /// </summary>
        public ObservableCollection<ShareVia> Shared { get; private set; }

        /// <summary>
        /// Gets or sets the time period in days (1, 3, or 7)
        /// </summary>
        public int TimePeriod
        {
            get
            {
                return this.MostEmailed.TimePeriod;
            }

            set
            {
                this.MostEmailed.TimePeriod = value;
                this.MostShared.TimePeriod = value;
                this.MostViewed.TimePeriod = value;
            }
        }

        /// <summary>
        /// Gets or sets the maximum number of results
        /// </summary>
        public int MaxResults
        {
            get
            {
                return this.MostEmailed.MaxResults;
            }
            
            set
            {
                this.MostEmailed.MaxResults = value;
                this.MostShared.MaxResults = value;
                this.MostViewed.MaxResults = value;

                this.NotifyPropertyChanged("MaxResults");
            }
        }

        /// <summary>
        /// Gets or sets the selected item
        /// </summary>
        public NYTimes.Data.MostPopularItem SelectedItem 
        { 
            get
            {
                return this.selectedItem;
            }

            set
            {
                if (this.selectedItem != value)
                {
                    this.selectedItem = value;

                    this.NotifyPropertyChanged("SelectedItem");
                }
            }
        }

        /// <summary>
        /// Dispose fo the resources
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);

            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Save the Settings
        /// </summary>
        internal void SaveSettings()
        {
            IsolatedStorageSettings.ApplicationSettings["MaxResults"] = this.MaxResults;

            foreach (var share in this.Shared)
            {
                IsolatedStorageSettings.ApplicationSettings[share.Id] = share.IsEnabled;
            }
        }

        /// <summary>
        /// Update the shared list
        /// </summary>
        internal void UpdateShared()
        {
            var query = from shared in this.Shared
                        where shared.IsEnabled
                        select shared.Id;

            if (query.Count() == 0)
            {
                this.MostShared.ShareTypes = string.Empty;
            }
            else
            {
                this.MostShared.ShareTypes = string.Join(";", query.ToArray());
            }
        }

        /// <summary>
        /// Dispose of the resources
        /// </summary>
        /// <param name="managedAndNative">managed and native</param>
        protected virtual void Dispose(bool managedAndNative)
        {
            if (this.MostEmailed != null)
            {
                this.MostEmailed.Dispose();

                this.MostEmailed = null;
            }

            if (this.MostShared != null)
            {
                this.MostShared.Dispose();

                this.MostShared = null;
            }

            if (this.MostViewed != null)
            {
                this.MostViewed.Dispose();

                this.MostViewed = null;
            }
        }

        /// <summary>
        /// Notify that the property has changed
        /// </summary>
        /// <param name="propertyName">the property name</param>
        private void NotifyPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Load the settings from isolated storage
        /// </summary>
        private void LoadSettings()
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains("MaxResults"))
            {
                this.MaxResults = (int)IsolatedStorageSettings.ApplicationSettings["MaxResults"];
            }

            foreach (var share in this.Shared)
            {
                if (IsolatedStorageSettings.ApplicationSettings.Contains(share.Id))
                {
                    share.IsEnabled = (bool)IsolatedStorageSettings.ApplicationSettings[share.Id];
                }
            }
        }
    }
}